﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Biomedica.Propability.StateMachine
{
    /// <summary>
    /// This is a factory that build a state machine
    /// </summary>
    public class StateMachineFactory
    {
        public static StateContext CreateStateMachine(State[] State)
        {
            StateMachineEngine eng = new StateMachineEngine();
            StateContext context = new StateContext();
            context.initEnvirunments();

            for (int i = 0; i < State.Length; i++)
                eng.StateCollection.Add(State[i].Name, State[i]);
            
            context.setStateMachineEngine(eng);
           
            return context;
        }
        public static StateContext CreateStateMachine(String filename)
        {
           
            StateMachineEngine eng = new StateMachineEngine();
            StateContext context = new StateContext();
            context.initEnvirunments();

            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filename);
                /// Create The registery Envirunments


                foreach (var elem in doc.GetElementsByTagName("Regestrer"))
                {
                    String key = ((XmlElement)elem).GetElementsByTagName("Key")[0].InnerText;
                    Boolean InitValue
                        = Convert.ToBoolean(((XmlElement)elem).GetElementsByTagName("InitValue")[0].InnerText);
                    context.EnvirunmentCollection.Add(key, InitValue);
                }


                // Create and Connect States


                foreach (var nelem in doc.GetElementsByTagName("State"))
                {
                    String statename = ((XmlElement)nelem).GetElementsByTagName("Name")[0].InnerText;
                    State s = new State(statename);


                    var transcoll = ((XmlElement)nelem).ChildNodes[1].ChildNodes;
                    foreach (XmlElement innerelem in transcoll)
                    {
                        string logic = innerelem.GetElementsByTagName("logic")[0].InnerText;
                        string parameter = innerelem.GetElementsByTagName("parameter")[0].InnerText;
                        string nextstate = innerelem.GetElementsByTagName("nextstate")[0].InnerText;

                        s.Add(new Triggers(nextstate, parameter, logic));
                       

                    }

                    eng.StateCollection.Add(statename, s);


                }

            }
            catch (Exception err)
            {
                throw new Exception("Error While Parsing xml file");
            }

            context.setStateMachineEngine(eng);
             return context;
        }

        public static StateContext CreateTwoStateSM(String Gard1, String Gard2,String parametgername)
        {
            State[] s = new State[2];
            s[0] = new State(Gard1);
            s[1]= new State(Gard2);
            StateContext context = CreateStateMachine(s);

            context.EnvirunmentCollection.Add(parametgername, false);


            context.getStateMachineEngine().StateCollection[Gard1].Add(new Triggers(Gard2,parametgername,true));
            context.getStateMachineEngine().StateCollection[Gard1].Add(new Triggers(Gard1, parametgername, false));
            context.getStateMachineEngine().StateCollection[Gard2].Add(new Triggers(Gard1, parametgername, true));
            context.getStateMachineEngine().StateCollection[Gard2].Add(new Triggers(Gard2, parametgername, false));

            return context;
        }

        
    
    }
}
